package cz.semjobKB.gui;

import com.vaadin.server.Page;
import com.vaadin.ui.*;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import cz.semjobKB.controller.Controller;
import cz.semjobKB.knowledge.api.IExtractedKnowledge;
import cz.semjobKB.knowledge.api.ITerminologyItem;
import cz.semjobKB.knowledge.api.ITripleItem;
import cz.semjobKB.virtuoso.document.api.IDocumentDetail;
import cz.semjobKB.virtuoso.document.api.IResourceDetail;
import cz.semjobKB.virtuoso.document.api.ITerminologyDetail;
import cz.semjobKB.virtuoso.document.api.ITripleDbItem;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.File;
import java.util.LinkedHashMap;
import java.util.List;


@SuppressWarnings({ "restriction" })
@Component
public class DisplayLayout extends VerticalLayout {

	private VerticalLayout vertDocument = new VerticalLayout();
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	@PostConstruct
    protected void init() {		
	}

    /**
     * Shows document detail its statistic, list of triples and terminologies
     * @param documentDetail    Document detail
     */
	public void showDocumentDetail(IDocumentDetail documentDetail) {
		this.removeAllComponents();		
		this.addComponent(new DocumentInfo().fillDocumentInfo(documentDetail));
		this.setSizeFull();		
	}

    /**
     * Shows document after extraction process, list of found triple and terminologies. User can select what to add
     * and what to discard.
     * @param triples           Map of triples and flag if they exist already in DB
     * @param terminology       Map of terminologies and flag if they exist already in DB
     * @param originalKnowledge Extracted knowledge
     * @param docToProcess      Document which is being processed
     * @param controller        Reference to the controller class
     */
	public void showDocumentPreSave(LinkedHashMap<ITripleItem, Boolean> triples, 
			LinkedHashMap<ITerminologyItem, Boolean> terminology, 
			IExtractedKnowledge originalKnowledge,
			File docToProcess, Controller controller) {
		this.removeAllComponents();		
		this.addComponent(new SelectKnowledgeLayout().suggestExtractedKnowledge(
				triples, terminology, originalKnowledge, docToProcess, controller));
		this.setSizeFull();		
	}

    /**
     * Shows detail about terminology
     * @param terminologyDetails    List of terminologies to display
     */
	public void showTerminologyDetail(List<ITerminologyDetail> terminologyDetails) {
		this.removeAllComponents();		
		for (ITerminologyDetail item : terminologyDetails) {
			HorizontalLayout horizontalLayout = new HorizontalLayout();
			horizontalLayout.addComponent(new Label("Resource Uri: "));
			horizontalLayout.addComponent(new Label(item.getResourceUri()));
			this.addComponent(horizontalLayout);
			HorizontalLayout lemmaLayout = new HorizontalLayout();
			lemmaLayout.addComponent(new Label("Resource Lemma: "));
			lemmaLayout.addComponent(new Label(item.getResourceLemma()));
			this.addComponent(lemmaLayout);
			VerticalLayout vertical = new VerticalLayout();
			vertical.addComponent(new Label("Resource text representation: "));			
			for (String text : item.getResourceRepresentation()) {
				vertical.addComponent(new Label(text));
			}
			this.addComponent(vertical);
			
			HorizontalLayout total = new HorizontalLayout();			
			total.addComponent(new Label("Overall Frequency: "));
			total.addComponent(new Label(item.getOverallFrequency().toString()));
			this.addComponent(total);
			
			HorizontalLayout totalCount = new HorizontalLayout();			
			totalCount.addComponent(new Label("Document containing: "));
			totalCount.addComponent(new Label(item.getTotalCount().toString()));
			this.addComponent(totalCount);
		}
		
	}

    /**
     * Shows detail about term(Subject or object)
     * @param resourceDetail    List of resources to display
     */
	public void showTermDetail(List<IResourceDetail> resourceDetail) {
		this.removeAllComponents();		
		for (IResourceDetail item : resourceDetail) {
			HorizontalLayout horizontalLayout = new HorizontalLayout();
			horizontalLayout.addComponent(new Label("Resource Uri: "));
			horizontalLayout.addComponent(new Label(item.getResourceUri()));
			this.addComponent(horizontalLayout);
			HorizontalLayout lemmaLayout = new HorizontalLayout();
			lemmaLayout.addComponent(new Label("Resource Lemma: "));
			lemmaLayout.addComponent(new Label(item.getResourceLemma()));
			this.addComponent(lemmaLayout);
			VerticalLayout vertical = new VerticalLayout();
			vertical.addComponent(new Label("Resource text representation: "));			
			for (String text : item.getResourceRepresentation()) {
				vertical.addComponent(new Label(text));
			}
			this.addComponent(vertical);
		}
	}

    /**
     * Displays matched triples
     * @param triples   List of matched triples
     */
	@SuppressWarnings("unchecked")
	public void showSuggestedTriples(List<ITripleDbItem> triples) {
		this.removeAllComponents();
		if(triples == null || triples.size() == 0) {
			return;
		}
		Table triplesList = new Table();
				
		triplesList.addContainerProperty("Subject", String.class,  null);
		triplesList.addContainerProperty("Predicate", String.class,  null);
		triplesList.addContainerProperty("Object", String.class, null);		
		
		for(ITripleDbItem resourceDetail : triples) {
			Object id = triplesList.addItem();
			triplesList.getContainerProperty(id,"Subject").setValue(resourceDetail.getSubject().getResourceLemma()); 
			triplesList.getContainerProperty(id,"Predicate").setValue(resourceDetail.getPredicate().getResourceLemma());
			triplesList.getContainerProperty(id,"Object").setValue(resourceDetail.getObject().getResourceLemma());
		}		
		triplesList.setSizeFull();		
		this.addComponent(triplesList);		
		this.setSizeFull();
	}

    /*
        General exception
     */
	public void showError(String errorMessage) {
		new Notification("Error occured: " + errorMessage,
                Notification.Type.ERROR_MESSAGE)
		.show(Page.getCurrent());
	}

    /**
     * Displays result of terminology or triple search for document request
     * @param documents Result of document search
     */
	public void showResultDocuments(final List<IDocumentDetail> documents) {
		this.removeAllComponents();
		this.setSizeFull();
		HorizontalSplitPanel splitPanel = new HorizontalSplitPanel();
		splitPanel.setSplitPosition(20);
		splitPanel.setSizeFull();
		splitPanel.setLocked(true);
		VerticalLayout verticalLayout = new VerticalLayout();
		for (IDocumentDetail docDetail : documents) {
			Button button = new Button(docDetail.getDocumentName());
			final IDocumentDetail docTest = docDetail;
			button.addClickListener(new ClickListener() {
				
				/**
				 * 
				 */
				private static final long serialVersionUID = 1L;

				public void buttonClick(ClickEvent event) {
					vertDocument.removeAllComponents();
					vertDocument.addComponent(new DocumentInfo().fillDocumentInfo(docTest));
					vertDocument.setSizeFull();
				}
			});
			button.setSizeFull();
			verticalLayout.addComponent(button);
		}
		splitPanel.addComponent(verticalLayout);
		splitPanel.addComponent(vertDocument);		
		this.addComponent(splitPanel);
		
	}
}
